package com.zy.is.controller;

import cn.hutool.http.server.HttpServerRequest;
import com.zy.is.common.api.Result;
import com.zy.is.common.config.AppConstants;
import com.zy.is.domain.SysUser;
import com.zy.is.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @ClassName: LoginController
 * @Description:
 * @Author: Yanzy
 * @Data: 2021/4/2 16:44
 * @Source: 1.0
 */
@Slf4j
@Controller
@AllArgsConstructor
public class LoginController {

    private final SysUserService sysUserService;

    /**
     * 跳转登录页面
     *
     * @return url
     */
    @GetMapping("/login")
    public String login() {

        // 从session中获取登录信息
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            Session session = subject.getSession();
            if (session != null) {
                Object user = session.getAttribute("user");
                if (user != null) {
                    return "redirect:index";
                }
            }
        }
        return "login";
    }

    /**
     * 跳转到主页
     *
     * @return url
     */
    @GetMapping("/index")
    public String index() {
        log.info("======>>>> 正在跳转系统主页 ======>>>>");
        return "index";
    }

    /**
     * 登出 post方式
     * @return
     */
    @ResponseBody
    @PostMapping("/logout")
    public Result<String> logout() {

        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            SysUser sysUser = (SysUser) subject.getPrincipal();
            log.debug("{} - 用户退出...", sysUser.getLoginName());
            subject.logout();
        }
        return Result.success("退出成功");
    }

    /**
     * 未授权跳转
     * @return url
     */
    @GetMapping("/unauthorized")
    public String unauthorised() {
        return "/error/unauthorized";
    }

    /**
     * 登录操作
     *
     * @param loginName 登录名
     * @param loginPwd  登录密码
     * @return url
     */
    @ResponseBody
    @PostMapping("/doLogin")
    public Result<String> doLogin(String loginName, String loginPwd, String captcha, boolean rememberMe, HttpServletRequest request) {

        // 验证码校验
        String sessionCaptcha = (String) request.getSession().getAttribute(AppConstants.CAPTCHA_KEY);
        if (!StringUtils.equalsIgnoreCase(captcha, sessionCaptcha)) {
            return Result.error("验证码不匹配!");
        }
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginName, loginPwd, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(usernamePasswordToken);

            // 获取登录的用户
            SysUser user = (SysUser) subject.getPrincipal();

            // 将用户信息存入cookie中
            Session session = subject.getSession();
            session.setAttribute("user", user);
            // 删除session验证码
            request.getSession().removeAttribute(AppConstants.CAPTCHA_KEY);
        } catch (UnknownAccountException e) {
            log.debug("未知用户! {}", e.getMessage());
            return Result.error("未知用户!");
        } catch (IncorrectCredentialsException e) {
            log.debug("{} - 用户登录密码校验异常! {}", loginName, e.getMessage());
            return Result.error("密码校验异常!");
        } catch (AuthenticationException e) {
            log.debug("{} - 用户登录认证失败! {}", loginName, e.getMessage());
            return Result.error("登录失败!");
        } catch (Exception e) {
            log.debug("{} - 用户登录异常! {}", loginName, e.getMessage());
            return Result.error("登录异常!");
        }
        return Result.success("登录成功!");
    }
}
